using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WenYu.Core.Errors
{
    /// <summary>
    /// 控制台错误格式化器 - 实现8段式彩色输出
    /// </summary>
    public class ConsoleErrorFormatter : IErrorFormatter
    {
        private readonly bool _useColor;
        
        public ConsoleErrorFormatter(bool useColor = true)
        {
            _useColor = useColor;
        }
        
        /// <summary>
        /// 格式化错误为字符串（不包含颜色）
        /// </summary>
        public string Format(CompileError error)
        {
            var sb = new StringBuilder();
            
            // 1️⃣ 错误标题
            sb.AppendLine(FormatTitle(error));
            sb.AppendLine();
            
            // 2️⃣ 错误位置
            sb.AppendLine(FormatLocation(error));
            sb.AppendLine();
            
            // 3️⃣ + 4️⃣ 源代码和错误指示
            var sourceContext = FormatSourceContext(error);
            if (!string.IsNullOrEmpty(sourceContext))
            {
                sb.AppendLine(sourceContext);
                sb.AppendLine();
            }
            
            // 5️⃣ 问题解释
            if (!string.IsNullOrEmpty(error.Explanation))
            {
                sb.AppendLine("❓ 问题解释：");
                sb.AppendLine(IndentText(error.Explanation));
                sb.AppendLine();
            }
            
            // 6️⃣ 解决建议
            if (error.Suggestions.Count > 0)
            {
                sb.AppendLine("💡 解决建议：");
                for (int i = 0; i < error.Suggestions.Count; i++)
                {
                    sb.AppendLine($"   {i + 1}. {error.Suggestions[i]}");
                }
                sb.AppendLine();
            }
            
            // 7️⃣ 相关知识
            if (error.RelatedKnowledge.Count > 0)
            {
                sb.AppendLine("📚 相关知识：");
                for (int i = 0; i < error.RelatedKnowledge.Count; i++)
                {
                    var knowledge = error.RelatedKnowledge[i];
                    var url = i < error.RelatedKnowledgeUrls.Count ? error.RelatedKnowledgeUrls[i] : "";
                    
                    if (!string.IsNullOrEmpty(url))
                    {
                        sb.AppendLine($"   • {knowledge}");
                        sb.AppendLine($"     🌐 {url}");
                    }
                    else
                    {
                        sb.AppendLine($"   • {knowledge}");
                    }
                }
                sb.AppendLine();
            }
            
            // 8️⃣ 更多帮助
            if (error.MoreHelp.Count > 0)
            {
                sb.AppendLine("🔗 更多帮助：");
                for (int i = 0; i < error.MoreHelp.Count; i++)
                {
                    var help = error.MoreHelp[i];
                    var url = i < error.MoreHelpUrls.Count ? error.MoreHelpUrls[i] : "";
                    
                    if (!string.IsNullOrEmpty(url))
                    {
                        sb.AppendLine($"   • {help}");
                        sb.AppendLine($"     🌐 {url}");
                    }
                    else
                    {
                        sb.AppendLine($"   • {help}");
                    }
                }
                sb.AppendLine();
            }
            
            return sb.ToString();
        }
        
        /// <summary>
        /// 直接输出错误到控制台（支持彩色）
        /// </summary>
        public void Print(CompileError error)
        {
            if (_useColor)
            {
                PrintWithColor(error);
            }
            else
            {
                Console.WriteLine(Format(error));
            }
        }
        
        /// <summary>
        /// 彩色输出
        /// </summary>
        private void PrintWithColor(CompileError error)
        {
            // 1️⃣ 错误标题
            PrintTitle(error);
            Console.WriteLine();
            
            // 2️⃣ 错误位置
            PrintLocation(error);
            Console.WriteLine();
            
            // 3️⃣ + 4️⃣ 源代码和错误指示
            PrintSourceContext(error);
            
            // 5️⃣ 问题解释
            if (!string.IsNullOrEmpty(error.Explanation))
            {
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("❓ 问题解释：");
                Console.ResetColor();
                Console.WriteLine(IndentText(error.Explanation));
            }
            
            // 6️⃣ 解决建议
            if (error.Suggestions.Count > 0)
            {
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("💡 解决建议：");
                Console.ResetColor();
                for (int i = 0; i < error.Suggestions.Count; i++)
                {
                    Console.WriteLine($"   {i + 1}. {error.Suggestions[i]}");
                }
            }
            
            // 7️⃣ 相关知识
            if (error.RelatedKnowledge.Count > 0)
            {
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("📚 相关知识：");
                Console.ResetColor();
                for (int i = 0; i < error.RelatedKnowledge.Count; i++)
                {
                    var knowledge = error.RelatedKnowledge[i];
                    var url = i < error.RelatedKnowledgeUrls.Count ? error.RelatedKnowledgeUrls[i] : "";
                    
                    Console.WriteLine($"   • {knowledge}");
                    if (!string.IsNullOrEmpty(url))
                    {
                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                        Console.WriteLine($"     🌐 {url}");
                        Console.ResetColor();
                    }
                }
            }
            
            // 8️⃣ 更多帮助
            if (error.MoreHelp.Count > 0)
            {
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Blue;
                Console.WriteLine("🔗 更多帮助：");
                Console.ResetColor();
                for (int i = 0; i < error.MoreHelp.Count; i++)
                {
                    var help = error.MoreHelp[i];
                    var url = i < error.MoreHelpUrls.Count ? error.MoreHelpUrls[i] : "";
                    
                    Console.WriteLine($"   • {help}");
                    if (!string.IsNullOrEmpty(url))
                    {
                        Console.ForegroundColor = ConsoleColor.DarkCyan;
                        Console.WriteLine($"     🌐 {url}");
                        Console.ResetColor();
                    }
                }
            }
            
            Console.WriteLine();
        }
        
        // ========== 私有辅助方法 ==========
        
        private string FormatTitle(CompileError error)
        {
            var severityIcon = error.Severity switch
            {
                ErrorSeverity.Error => "❌",
                ErrorSeverity.Warning => "⚠️",
                ErrorSeverity.Info => "ℹ️",
                ErrorSeverity.Hint => "💡",
                _ => "❌"
            };
            
            var title = $"{severityIcon} {GetSeverityText(error.Severity)}：{error.Title}";
            var border = new string('═', Math.Max(40, title.Length + 2));
            
            return $"╔{border}╗\n║ {title.PadRight(border.Length - 2)} ║\n╚{border}╝";
        }
        
        private void PrintTitle(CompileError error)
        {
            var severityIcon = error.Severity switch
            {
                ErrorSeverity.Error => "❌",
                ErrorSeverity.Warning => "⚠️",
                ErrorSeverity.Info => "ℹ️",
                ErrorSeverity.Hint => "💡",
                _ => "❌"
            };
            
            var color = error.Severity switch
            {
                ErrorSeverity.Error => ConsoleColor.Red,
                ErrorSeverity.Warning => ConsoleColor.Yellow,
                ErrorSeverity.Info => ConsoleColor.Cyan,
                ErrorSeverity.Hint => ConsoleColor.Blue,
                _ => ConsoleColor.Red
            };
            
            var title = $"{severityIcon} {GetSeverityText(error.Severity)}：{error.Title}";
            var border = new string('═', Math.Max(40, title.Length + 2));
            
            Console.ForegroundColor = color;
            Console.WriteLine($"╔{border}╗");
            Console.WriteLine($"║ {title.PadRight(border.Length - 2)} ║");
            Console.WriteLine($"╚{border}╝");
            Console.ResetColor();
        }
        
        private string GetSeverityText(ErrorSeverity severity)
        {
            return severity switch
            {
                ErrorSeverity.Error => "错误",
                ErrorSeverity.Warning => "警告",
                ErrorSeverity.Info => "提示",
                ErrorSeverity.Hint => "学习提示",
                _ => "错误"
            };
        }
        
        private string FormatLocation(CompileError error)
        {
            var sb = new StringBuilder();
            sb.Append($"📍 位置：第 {error.Line} 行，第 {error.Column} 列");
            
            if (!string.IsNullOrEmpty(error.FilePath))
            {
                sb.AppendLine();
                sb.Append($"📄 文件：{error.FilePath}");
            }
            
            return sb.ToString();
        }
        
        private void PrintLocation(CompileError error)
        {
            Console.ForegroundColor = ConsoleColor.DarkGray;
            Console.Write("📍 位置：");
            Console.ResetColor();
            Console.WriteLine($"第 {error.Line} 行，第 {error.Column} 列");
            
            if (!string.IsNullOrEmpty(error.FilePath))
            {
                Console.ForegroundColor = ConsoleColor.DarkGray;
                Console.Write("📄 文件：");
                Console.ResetColor();
                Console.WriteLine(error.FilePath);
            }
        }
        
        private string FormatSourceContext(CompileError error)
        {
            if (string.IsNullOrEmpty(error.SourceCode))
                return "";
            
            var lines = error.SourceCode.Split('\n');
            var errorLine = error.Line - 1; // 转为0-based索引
            
            if (errorLine < 0 || errorLine >= lines.Length)
                return "";
            
            var sb = new StringBuilder();
            var startLine = Math.Max(0, errorLine - error.ContextLinesBefore);
            var endLine = Math.Min(lines.Length - 1, errorLine + error.ContextLinesAfter);
            
            for (int i = startLine; i <= endLine; i++)
            {
                var lineNum = i + 1;
                var lineNumStr = lineNum.ToString().PadLeft(3);
                
                if (i == errorLine)
                {
                    // 错误行
                    sb.AppendLine($"{lineNumStr} | {lines[i]}");
                    
                    // 错误指示符
                    var pointer = new string(' ', error.Column - 1) + "^";
                    if (error.ErrorLength > 1)
                    {
                        pointer += new string('^', error.ErrorLength - 1);
                    }
                    sb.AppendLine($"     | {pointer} ❌ 这里有错误");
                }
                else
                {
                    // 上下文行
                    sb.AppendLine($"{lineNumStr} | {lines[i]}");
                }
            }
            
            return sb.ToString();
        }
        
        private void PrintSourceContext(CompileError error)
        {
            if (string.IsNullOrEmpty(error.SourceCode))
                return;
            
            var lines = error.SourceCode.Split('\n');
            var errorLine = error.Line - 1; // 转为0-based索引
            
            if (errorLine < 0 || errorLine >= lines.Length)
                return;
            
            Console.WriteLine();
            
            var startLine = Math.Max(0, errorLine - error.ContextLinesBefore);
            var endLine = Math.Min(lines.Length - 1, errorLine + error.ContextLinesAfter);
            
            for (int i = startLine; i <= endLine; i++)
            {
                var lineNum = i + 1;
                var lineNumStr = lineNum.ToString().PadLeft(3);
                
                if (i == errorLine)
                {
                    // 错误行 - 高亮显示
                    Console.ForegroundColor = ConsoleColor.DarkGray;
                    Console.Write($"{lineNumStr} | ");
                    Console.ResetColor();
                    Console.WriteLine(lines[i]);
                    
                    // 错误指示符
                    Console.ForegroundColor = ConsoleColor.Red;
                    var pointer = new string(' ', error.Column - 1) + "^";
                    if (error.ErrorLength > 1)
                    {
                        pointer += new string('^', error.ErrorLength - 1);
                    }
                    Console.Write($"     | {pointer}");
                    Console.ResetColor();
                    Console.WriteLine(" ❌ 这里有错误");
                }
                else
                {
                    // 上下文行
                    Console.ForegroundColor = ConsoleColor.DarkGray;
                    Console.Write($"{lineNumStr} | ");
                    Console.ResetColor();
                    Console.ForegroundColor = ConsoleColor.Gray;
                    Console.WriteLine(lines[i]);
                    Console.ResetColor();
                }
            }
        }
        
        private string IndentText(string text, int spaces = 3)
        {
            var indent = new string(' ', spaces);
            var lines = text.Split('\n');
            return string.Join("\n", lines.Select(line => indent + line));
        }
    }
}

